/***
	Copyright (c) 2008-2009 Jesse Banet, Feanil J. Patel, and Roberto C. Serrano
	
	Licensed under the Apache License, Version 2.0 (the "License"); you may
	not use this file except in compliance with the License. You may obtain
	a copy of the License at
		http://www.apache.org/licenses/LICENSE-2.0
	Unless required by applicable law or agreed to in writing, software
	distributed under the License is distributed on an "AS IS" BASIS,
	WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
	See the License for the specific language governing permissions and
	limitations under the License.
*/

package com.bikerolas;


import java.util.Timer;

import android.app.Activity;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.media.MediaPlayer;
import android.os.Binder;
import android.os.Handler;
import android.os.IBinder;
import android.os.PowerManager;
import android.util.Log;
import android.widget.Toast;

public class FlingService extends Service implements SensorEventListener{
//public class ScreamService extends Service implements SensorListener{
	
	public static ServiceUpdateUIListener UI_UPDATE_LISTENER;
	private static Fling MAIN_ACTIVITY;
	
	//We need the handler to talk to the 
	private Handler handler = new Handler();
	public static final String MYPREFS = "screamSharedPrefs";
	private boolean runAtBoot=false;  //From settings	
	private boolean serviceIsRunning=false;  //From settings		
	private boolean mNeedCheckAutoStart = false;   //Was the service started at boot
	private boolean wakeLockPref = false;
	
	//This should be very different... we need to create a sensorListener
	//   at the end...  
	private Timer timer = new Timer();
	private MediaPlayer scream;
//	PowerManager.WakeLock wakeLock;
	private double previous_magnitude;
	private int state; 
	private MediaPlayer ugh;
	private MediaPlayer wee;
	private long time;
	private static final long UPDATE_INTERVAL = 5000;
	
	public interface ServiceUpdateUIListener {
		public void updateUI();
	}//end interface ServiceUpdateUIListener

    public class LocalBinder extends Binder {
    	FlingService getService() {
            return FlingService.this;
        }
    }	

    @Override
    public void onStart(Intent intent, int startId) {
        super.onStart(intent, startId);
        
//		SharedPreferences mySharedPrefs = getSharedPreferences(MYPREFS, Activity.MODE_PRIVATE);
//		runAtBoot = mySharedPrefs.getBoolean("runAtBoot", false);
//		wakeLockPref = mySharedPrefs.getBoolean("wakeLock", false);

	

		mNeedCheckAutoStart = intent.getBooleanExtra("onBoot", false);
        if (mNeedCheckAutoStart==true && runAtBoot==false)
		{
//			Log.i("ScreamService", "Sorry but we were not suppoused to start at boot... stopping service... ");		
			this.stopSelf();
		}
    }
    
	//------------------------------------------------------------------
	// hooks into other activities
	//------------------------------------------------------------------
	public static void setMainActivity(Fling activity) {
	  MAIN_ACTIVITY = activity;
	}

	public static void setUpdateListener(ServiceUpdateUIListener l) {
	  UI_UPDATE_LISTENER = l;
	}
	
	
	@Override
	public void onCreate() {
		super.onCreate();

		Toast.makeText(this, "Service Started.", Toast.LENGTH_LONG).show();
        Log.d("ScreamService", "onCreate, checkAutoStart=" + mNeedCheckAutoStart); 
//		If not run at boot and service started at boot
      	Log.d("ScreamService", "RunAtBoot:" + runAtBoot + ", AutoStart:" + mNeedCheckAutoStart);		
					
		//Create a sensor manager for the accelerometer.
    	SensorManager mSensorMgr = (SensorManager) this.getSystemService(Context.SENSOR_SERVICE);
    	// Add a listener to the sensor manager.
    	mSensorMgr.registerListener(this,
    			mSensorMgr.getDefaultSensor(Sensor.TYPE_ACCELEROMETER),
    			SensorManager.SENSOR_DELAY_GAME);

		scream = MediaPlayer.create(getBaseContext(),R.raw.scream);
		ugh = MediaPlayer.create(getBaseContext(), R.raw.ugh);
		wee = MediaPlayer.create(getBaseContext(), R.raw.wee);
		
		SharedPreferences mySharedPrefs = getSharedPreferences(MYPREFS, Activity.MODE_PRIVATE);
		runAtBoot = mySharedPrefs.getBoolean("runAtBoot", false);		
		wakeLockPref = mySharedPrefs.getBoolean("wakeLock", false);
		Log.i("ScreamService", "WakeLockPref: " + wakeLockPref);	
		
		// Keep the cpu running so we can continue to get sensor information
//		if ( wakeLockPref && ( wakeLock == null || !(wakeLock.isHeld()) )) {
//				PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
//				wakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, getClass().getSimpleName());
//				wakeLock.acquire();
//		        Toast.makeText(this, "We acquired a wakeLock, say good-bye to your battery!", Toast.LENGTH_LONG).show();			
//				Log.i(getClass().getSimpleName(), "We acquire a wakeLock!");	        
//		} else {
//			Log.i(getClass().getSimpleName(), "Acquire a wakeLock failled!");		        
//		}
		
//		timer.scheduleAtFixedRate(
//			      new TimerTask() {
//			    	  public void run() { 
//			    	  handler.post(new Runnable() {
//                        public void run() {
//                      	Log.i(getClass().getSimpleName(), "Beat!!!");					  
//                        }
//			    	  }); 			    	  
//			    	  }
//			      },
//			      0,
//			      UPDATE_INTERVAL);
		
		if (MAIN_ACTIVITY != null)
		{
	        Toast.makeText(this, "The Fling Service has been started!", Toast.LENGTH_SHORT).show(); 			
			Log.i(getClass().getSimpleName(), "Service Started");	
	        Toast.makeText(this, "The Fling Service has been started!", Toast.LENGTH_SHORT).show();				
	    	serviceIsRunning = true;
	    	savePrefs();		
		}		
		
	}

	public void onSensorChanged(SensorEvent event) {
		// Get Sensor Values
		float[] values = event.values;

		double x = values[SensorManager.DATA_X];
		double y = values[SensorManager.DATA_Y];
		double z = values[SensorManager.DATA_Z];

		// Do sensor math		
		double magnitude = Math.sqrt(x*x + y*y + z*z);
		double slope = Math.abs(magnitude - previous_magnitude);
		previous_magnitude = magnitude;
				
//		if ((slope > 5.5 && slope < 12.0) || magnitude < 2.0){
//			//Check value and do toast/make sound
//			Log.d("ScreamService", "Value of the magnitude " + magnitude);
//			Log.d("ScreamService", "Value of the slope " + slope);
//
//			mediaPlayer.start();
//		}
		Log.d("ScreamService", "XYZ: " + x + "," + y + "," + z );
//		Log.d("ScreamService", "Value of the magnitude " + magnitude + ", state:" + state);
		if (state == 0) {
			if (magnitude < 2.0){
				ugh.stop();
				ugh.release();
				scream.start();
//		        Toast.makeText(this, "Aaaaahhhhh!", Toast.LENGTH_SHORT).show();				
				
				state = 1;
				ugh = MediaPlayer.create(getBaseContext(), R.raw.ugh);
			
				
			}else if( magnitude > 17.0 && x < 2.0 && y < 2.0 ){
				state = 2;
				time = System.currentTimeMillis();
			}
		}else if (state==1){
			if (magnitude > 12.0){
				scream.stop();
				scream.release();
				ugh.start();
				scream = MediaPlayer.create(getBaseContext(), R.raw.scream);
//		        Toast.makeText(this, "Ugh!", Toast.LENGTH_SHORT).show(); 
				
				state = 0;
			}else if (!scream.isPlaying()){						
				state = 0;
			}
		}else if (state==2){
				if(magnitude < 2.0){
					wee.start();
//			        Toast.makeText(this, "Weeeeee!", Toast.LENGTH_SHORT).show(); 					
					state = 3;
				} else if ( time + 1000 < System.currentTimeMillis()){
					state = 3;
				}
		}else if (state==3){
			if (!wee.isPlaying()) {
				state = 0;
				wee.stop();
				wee.release();
				wee = MediaPlayer.create(getBaseContext(), R.raw.wee);					
			}
		}

	};

	
	@Override
	public void onDestroy() {
		super.onDestroy();

		if (timer != null) timer.cancel();
    	SensorManager mSensorMgr = (SensorManager) this.getSystemService(Context.SENSOR_SERVICE);
    	mSensorMgr.unregisterListener(this);
    	scream.release();
//		if (wakeLock != null && wakeLock.isHeld()){
//			wakeLock.release();
//	        Toast.makeText(this, "We released the wakeLock, good call!", Toast.LENGTH_SHORT).show();						
//		}
    	serviceIsRunning = false;
    	savePrefs();
        Toast.makeText(this, "The Fling Service has been stopped!", Toast.LENGTH_SHORT).show();    	
		if (MAIN_ACTIVITY != null)
		{
        	Log.i(getClass().getSimpleName(), "Service stopped!");		
		}		    
	}

	
    @Override
    public IBinder onBind(Intent intent) {
        return mBinder;
    }

    // This is the object that receives interactions from clients.  See
    // RemoteService for a more complete example.
    private final IBinder mBinder = new LocalBinder();
	
	
//--------
	
	protected void savePrefs(){
		SharedPreferences mySharedPrefs = getSharedPreferences(MYPREFS, Activity.MODE_PRIVATE);
		SharedPreferences.Editor editor = mySharedPrefs.edit();
		
		Log.d(getClass().getSimpleName(), 
				"Changing service Preferences. serviceIsRunning = " + serviceIsRunning);
		editor.putBoolean("serviceIsRunning", serviceIsRunning);	
		editor.commit();
	}
	
	protected void loadPrefs(){
		SharedPreferences mySharedPrefs = getSharedPreferences(MYPREFS, Activity.MODE_PRIVATE);
		runAtBoot = mySharedPrefs.getBoolean("runAtBoot", false);
	}

	@Override
	public void onAccuracyChanged(Sensor sensor, int accuracy) {
		// TODO Auto-generated method stub
		
	}	

	
}


